/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
/*                                                                         */
/* Redistribution and use in source and binary forms, with or without      */
/* modification, are permitted provided that the following conditions      */
/* are met:                                                                */
/*                                                                         */
/*    1. Redistributions of source code must retain the above copyright    */
/* notice, this list of conditions and the following disclaimer.           */
/*    2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the     */
/* documentation and/or other materials provided with the distribution.    */
/*                                                                         */
/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "athd.h"

static int _dienow = 0;
static void _athd_stats_thread_cleanup(void *ctx);
static apr_pool_t *_pool_tmp = NULL;

apr_status_t
athd_stats_thread_setup(apr_pool_t *pglobal)
{
    int rv = APR_SUCCESS;
    rv = athd_stats_setup(pglobal);
    RV_OK = apr_pool_create(&_pool_tmp, pglobal);
    if (rv)
      {
	  athd_log_err(ATHD_CRIT, rv, "Stats Thread: Fatal error: ");
	  _dienow = 1;
      }
    return rv;
}


void *
athd_stats_thread(void *conf_ctx)
{
    int laststate, lasttype;
    apr_time_t time_nextrun = 0;
    athd_conf *conf = (athd_conf *) conf_ctx;
    apr_status_t rv = APR_SUCCESS;
    struct sigaction action = { NULL } ;
    
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &laststate);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &lasttype);
    pthread_cleanup_push((void *)_athd_stats_thread_cleanup, NULL);

    action.sa_handler = athd_connection_reset;
    sigaction(SIGPIPE, &action, 0);

    athd_log(ATHD_INFO, "Stats Thread: Enter");
    for (; (!_dienow) ;)
      {
	  apr_time_t time_now = apr_time_now();
	  pthread_testcancel();
	  if (time_nextrun <= time_now)
	    {
		time_nextrun = time_now + XTH_SEC(conf->stats_pulse);
		rv = athd_stats_refresh();
		if (!rv)
		  {
		      ath_upd_phys *phys = ath_phys_upd_alloc(_pool_tmp);
		      athd_stats_upd_phys(phys);
		      //DEBUGOUT("cpu: %f net: %f ld: %f mem: %f",
		      //   phys->cpu, phys->net, phys->ld, phys->mem);
		  }
		else
		  {
		      athd_log_err(ATHD_CRIT, rv, 
				   "Stats Thread: Fatal error: ");
		      _dienow = 1;
		  }
	    }
	  if (!rv)
	      apr_sleep((XTH_SEC(conf->stats_pulse)) / ATHD_STATS_PULSE_GRAIN);
      }

    pthread_cleanup_pop(1);
}

static void 
_athd_stats_thread_cleanup(void *ctx)
{
    athd_log(ATHD_INFO, "Stats Thread: Exit");
}
